package com.credithc.customers.dataservice.service.impl;

import com.credithc.baseserv.core.utils.UUIDUtils;
import com.credithc.customers.base.constants.CustomerConstants;
import com.credithc.customers.base.exception.CustomerException;
import com.credithc.customers.base.mapper.*;
import com.credithc.customers.base.po.*;
import com.credithc.customers.base.service.ICommonService;
import com.credithc.customers.base.utils.ClassUtils;
import com.credithc.customers.dataservice.constants.SyncTypeEnum;
import com.credithc.customers.dataservice.ro.CustomerAccountInfoRo;
import com.credithc.customers.dataservice.ro.CustomerProductInfoRo;
import com.credithc.customers.dataservice.ro.ProductInfoRo;
import com.credithc.customers.dataservice.service.SyncDataService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhukai
 * @date 2019/1/14 9:28
 */
@Service
@Slf4j
public class SyncDataServiceImpl implements SyncDataService {

    private final ICommonService commonService;

    private final ProductInfoMapper productMapper;

    private final CustomerProductMapper customerProductMapper;

    private final CustomerAccountMapper customerAccountMapper;

    private final CustomerRoleMapper customerRoleMapper;

    @Autowired
    private CustomerRelationInfoMapper customerRelationInfoMapper;

    @Autowired
    public SyncDataServiceImpl(ICommonService commonService, ProductInfoMapper productMapper, CustomerProductMapper customerProductMapper, CustomerAccountMapper customerAccountMapper, CustomerRoleMapper customerRoleMapper) {
        this.commonService = commonService;
        this.productMapper = productMapper;
        this.customerProductMapper = customerProductMapper;
        this.customerAccountMapper = customerAccountMapper;
        this.customerRoleMapper = customerRoleMapper;
    }

    @Override
    public void syncProduct(ProductInfoRo product) {
        String tableKey = product.getTableKey();
        String systemSign = product.getSystemSign();
        String subSystemSign = product.getSubSystemSign();
        ProductInfoPo po = commonService.getProductInfo(tableKey, systemSign, subSystemSign);
        String syncType = product.getSyncType();
        if (syncType.equals(SyncTypeEnum.UPDATE.getValue()) || syncType.equals(SyncTypeEnum.NEW.getValue())  ) {
            if (po == null) {
                addProduct(product);
            } else {
                updateProduct(po, product);
            }
        } else if (syncType.equals(SyncTypeEnum.DELETE.getValue()) && po != null) {
            deleteProduct(po);
        }
    }

    @Override
    public void syncProduct(List<ProductInfoRo> products) {
        for (ProductInfoRo ro : products) {
            syncProduct(ro);
        }
    }

    private void addProduct(ProductInfoRo ro) {
        try {
            ProductInfoPo po = new ProductInfoPo();
            BeanUtils.copyProperties(ro, po);
            po.setId(UUIDUtils.getUUID());
            po.setProductChannel(getSystemName(ro.getSystemSign(), ro.getSubSystemSign()));
            po.setProductType(ro.getProductType());
            po.setCreateTime(new Timestamp(System.currentTimeMillis()));
            productMapper.insert(po);
        } catch (CustomerException e) {
            log.error("插入产品信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMsg());
        } catch (Exception e) {
            log.error("插入产品信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
        }
    }

    private void updateProduct(ProductInfoPo po, ProductInfoRo ro) {
        try {
            BeanUtils.copyProperties(ro, po);
            po.setProductChannel(getSystemName(ro.getSystemSign(), ro.getSubSystemSign()));
            po.setProductType(ro.getProductType());
            po.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            productMapper.updateByPrimaryKey(po);
        } catch (CustomerException e) {
            log.error("更新产品信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMsg());
        } catch (Exception e) {
            log.error("更新产品信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
        }
    }

    private void deleteProduct(ProductInfoPo po) {
        try {
            productMapper.deleteByPrimaryKey(po);
        } catch (Exception e) {
            log.error("删除产品信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
        }
    }


    @Override
    public void syncCustomerProduct(CustomerProductInfoRo customerProduct) {
        String customerNo = customerProduct.getCustomerNo();
        String productNo = customerProduct.getProductNo();
        String systemSign = customerProduct.getSystemSign();
        String subSystemSign = customerProduct.getSubSystemSign();
        String tableName = customerProduct.getTableName();
        String syncType = customerProduct.getSyncType();
        CustomerProductInfoPo po = null;
        try {
            po = commonService.getCustomerProduct(customerProduct.getUserResourceId(), productNo, tableName, customerProduct.getTableKey());
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (syncType.equals(SyncTypeEnum.UPDATE.getValue()) || syncType.equals(SyncTypeEnum.NEW.getValue())) {
            if (po == null) {
                addCustomerProduct(customerProduct);
            } else {
                updateCustomerProduct(po, customerProduct);
            }
        } else if (syncType.equals(SyncTypeEnum.DELETE.getValue()) && po != null) {
            deleteCustomerProduct(po,customerProduct);
        }
    }

    private void addCustomerProduct(CustomerProductInfoRo ro) {
        try {
            CustomerProductInfoPo po = new CustomerProductInfoPo();
            BeanUtils.copyProperties(ro, po);
            po.setId(UUIDUtils.getUUID());
            po.setCreateTime(new Timestamp(System.currentTimeMillis()));
            po.setUserSourceId(ro.getUserResourceId());
            customerProductMapper.insert(po);
            String systemSign = ro.getSystemSign();
            String subSystemSign = ro.getSubSystemSign();
            //增加角色信息
            String customerRole = ro.getCustomerRole();
            if (StringUtils.isNotBlank(customerRole) && (ro.getProductStatus() == 2||ro.getProductStatus() == 5 || ro.getProductStatus() == 7) ) {
                addRoleInfo(ro.getUserResourceId(), ro.getCustomerNo(), systemSign, subSystemSign, customerRole, ro.getCustomerRoleStatus());
            }
            // 增加关系信息
           // addRealtion(ro, systemSign, subSystemSign, customerRole);

        } catch (CustomerException e) {
            log.error("插入客户产品信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMsg());
        } catch (Exception e) {
            log.error("插入客户产品信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
        }
    }

    private void addRealtion(CustomerProductInfoRo ro, String systemSign, String subSystemSign, String customerRole) {
        if (CustomerConstants.ROLE_TBR.equals(customerRole)||CustomerConstants.ROLE_BBR.equals(customerRole)){
            CustomerRelationInfoPo customerRelationInfoPo = new CustomerRelationInfoPo();
            customerRelationInfoPo.setRelationId(ro.getTableKey());
            customerRelationInfoPo.setCustomerNo(ro.getCustomerNo());
            customerRelationInfoPo.setRoleInRelation(CustomerConstants.ROLE_TBR.equals(customerRole)?2:3);
            CustomerRelationInfoPo customerRelationInfoPo1 = customerRelationInfoMapper.selectOne(customerRelationInfoPo);
            if (customerRelationInfoPo1 == null) {
                customerRelationInfoPo.setId(UUIDUtils.getUUID());
                customerRelationInfoPo.setCreateTime(new Timestamp(System.currentTimeMillis()));
                customerRelationInfoPo.setSubSystemSign(subSystemSign);
                customerRelationInfoPo.setSystemSign(systemSign);
                customerRelationInfoPo.setRelationId(ro.getTableKey());
                customerRelationInfoPo.setRelationSource(2);
                customerRelationInfoPo.setRoleInRelation(CustomerConstants.ROLE_TBR.equals(customerRole) ? 2 : 3);
                customerRelationInfoMapper.insert(customerRelationInfoPo);
            }
        }
    }

    private void updateCustomerProduct(CustomerProductInfoPo po, CustomerProductInfoRo ro) {
        try {
            BeanUtils.copyProperties(ro, po);
            po.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            customerProductMapper.updateByPrimaryKey(po);
            //根据订单信息修改角色可用性
            if (StringUtils.isNotBlank(ro.getCustomerRole()) && (ro.getProductStatus() == 2||ro.getProductStatus() == 5 || ro.getProductStatus() == 7) ) {
                //根据订单信息修改角色可用性
                Example example = new Example(CustomerProductInfoPo.class);
                Example.Criteria criteria = example.createCriteria();
                //criteria.andEqualTo("customerRole",ro.getCustomerRole());
                criteria.andEqualTo("subSystemSign",ro.getSubSystemSign());
                criteria.andEqualTo("customerNo",ro.getCustomerNo());
                List<Integer> list = new ArrayList(3);
                list.add(2);
                list.add(5);
                list.add(7);
                criteria.andNotIn("productStatus",list);
                int i = customerProductMapper.selectCountByExample(example);
                if (i<1) {
                    ro.setCustomerRoleStatus(CustomerConstants.CUSTOMER_ROLE_UNEFFECTIVE);
                }
            }
            addRoleInfo(ro.getUserResourceId(), ro.getCustomerNo(), po.getSystemSign(), po.getSubSystemSign(), ro.getCustomerRole(), ro.getCustomerRoleStatus());
            //addRealtion(ro, po.getSystemSign(), po.getSubSystemSign(), ro.getCustomerRole());
        } catch (Exception e) {
            log.error("更新客户产品信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
        }
    }

    private void deleteCustomerProduct(CustomerProductInfoPo po, CustomerProductInfoRo ro) {
        try {
            customerProductMapper.deleteByPrimaryKey(po);
            if (StringUtils.isNotBlank(ro.getCustomerRole()) && (ro.getProductStatus() == 2||ro.getProductStatus() == 5 || ro.getProductStatus() == 7) ) {
                //根据订单信息修改角色可用性
                Example example = new Example(CustomerProductInfoRo.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("customerRole",ro.getCustomerRole());
                criteria.andEqualTo("subSystemSign",ro.getSubSystemSign());
                criteria.andEqualTo("customerNo",ro.getCustomerNo());
                List<Integer> list = new ArrayList(3);
                list.add(2);
                list.add(5);
                list.add(7);
                criteria.andNotIn("productStatus",list);
                int i = customerProductMapper.selectCountByExample(example);
                if (i<1) {
                    ro.setCustomerRoleStatus(CustomerConstants.CUSTOMER_ROLE_UNEFFECTIVE);
                }
            }
            updateRoleInfoByProduct(ro.getUserResourceId(), po.getSystemSign(), po.getSubSystemSign(), ro.getCustomerRoleStatus());

        } catch (Exception e) {
            log.error("删除客户产品信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
        }
    }

    @Override
    public void syncCustomerProduct(List<CustomerProductInfoRo> customerProducts) {
        for (CustomerProductInfoRo ro : customerProducts) {
            syncCustomerProduct(ro);
        }
    }

    @Override
    public void syncCustomerAccount(CustomerAccountInfoRo ro) {
        String userSourceId = ro.getUserSourceId();
        String accountNo = ro.getAccountNo();
        String systemSign = ro.getSystemSign();
        String subSystemSign = ro.getSubSystemSign();
        String syncType = ro.getSyncType();
        CustomerAccountPo po;
        if (syncType.equals(SyncTypeEnum.UPDATE.getValue()) && (ro.getAccountType().equals(CustomerConstants.CUSTOMER_ACCOUNT_TYPE_BANK_CARD))) {
            log.info("ro.getOldAccountNo()---------------------------------------"+ro.getOldAccountNo());
            po = commonService.getCustomerAccount(userSourceId, ro.getOldAccountNo(), systemSign, subSystemSign,Integer.valueOf(ro.getAccountStatus()!=null?ro.getAccountStatus():CustomerConstants.STATUS_ACCOUNT_AVAILABLE));
        } else {
            log.info("accountNo---------------------------------------"+accountNo);
            po = commonService.getCustomerAccount(userSourceId, accountNo, systemSign, subSystemSign);
        }
        if (syncType.equals(SyncTypeEnum.UPDATE.getValue()) || syncType.equals(SyncTypeEnum.NEW.getValue())) {
            if (po == null) {
                addCustomerAccount(ro);
            } else {
                updateCustomerAccount(po, ro);
            }
        } else if (syncType.equals(SyncTypeEnum.DELETE.getValue()) && po != null) {
            deleteCustomerAccount(ro);
        }
    }

    private void addCustomerAccount(CustomerAccountInfoRo ro) {
        try {
            CustomerAccountPo po = new CustomerAccountPo();
            BeanUtils.copyProperties(ro, po);
            po.setId(UUIDUtils.getUUID());
            po.setUserSourceId(ro.getUserSourceId());
            po.setCreateTime(new Timestamp(System.currentTimeMillis()));
            CustomerAccountPo customerAccount = commonService.getCustomerAccount(po.getUserSourceId(), po.getAccountNo(), po.getSystemSign(), po.getSubSystemSign(), Integer.valueOf(po.getAccountStatus() != null ? po.getAccountStatus() : CustomerConstants.STATUS_ACCOUNT_AVAILABLE));
            if (customerAccount == null) {
                customerAccountMapper.insert(po);
            }
            //新增角色
            String customerRole = ro.getCustomerRole();
            if (StringUtils.isNotBlank(customerRole)) {
                addRoleInfo(ro.getUserSourceId(), ro.getCustomerNo(), ro.getSystemSign(), ro.getSubSystemSign(), customerRole, ro.getCustomerRoleStatus());
            }
        } catch (CustomerException e) {
            log.error("插入客户账户信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMsg());
        } catch (Exception e) {
            log.error("插入客户账户信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
        }
    }

    private void updateCustomerAccount(CustomerAccountPo po, CustomerAccountInfoRo ro) {
        try {
            Integer oldStatus = po.getAccountStatus();
            Integer newStatus = ro.getAccountStatus();
            BeanUtils.copyProperties(ro, po);
            if (oldStatus != null && newStatus != null ) {
                po.setAccountStatus(newStatus);
            } else {
                po.setAccountStatus(CustomerConstants.STATUS_ACCOUNT_AVAILABLE);
            }
            po.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            CustomerAccountPo customerAccount = commonService.getCustomerAccount(po.getUserSourceId(), po.getAccountNo(), po.getSystemSign(), po.getSubSystemSign(), Integer.valueOf(po.getAccountStatus() != null ? po.getAccountStatus() : CustomerConstants.STATUS_ACCOUNT_AVAILABLE));
            if (customerAccount == null || customerAccount.getId().equals(po.getId())) {
                customerAccountMapper.updateByPrimaryKey(po);
            }else{
                po.setAccountStatus(CustomerConstants.STATUS_ACCOUNT_UNAVAILABLE);
                customerAccountMapper.updateByPrimaryKey(po);
            }


            if (StringUtils.isNotBlank(ro.getCustomerNo())) {
                updateOtherSameCustomerNoAccount(ro);
            }
            //todo 更新角色
            updateRoleInfo(po.getUserSourceId(), po, ro);
        } catch (Exception e) {
            log.error("更新客户账户信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
        }
    }
    private void updateOtherSameCustomerNoAccount(CustomerAccountInfoRo ro){
        Example example = new Example(CustomerAccountPo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userSourceId", ro.getUserSourceId());
        criteria.andEqualTo("systemSign", ro.getSystemSign());
        criteria.andEqualTo("subSystemSign", ro.getSubSystemSign());
        criteria.andEqualTo("accountType",CustomerConstants.CUSTOMER_ACCOUNT_TYPE_BANK_CARD);
        CustomerAccountPo accountPo = new CustomerAccountPo();
        accountPo.setCustomerNo(ro.getCustomerNo());
        accountPo.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        customerAccountMapper.updateByExampleSelective(accountPo, example);
    }


    private void deleteCustomerAccount(CustomerAccountInfoRo ro) {
        try {
            Example example = new Example(CustomerAccountPo.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("userSourceId",ro.getUserSourceId());
            criteria.andEqualTo("systemSign",ro.getSystemSign());
            criteria.andEqualTo("subSystemSign",ro.getSubSystemSign());
            CustomerAccountPo po = new CustomerAccountPo();
            po.setAccountStatus(CustomerConstants.STATUS_ACCOUNT_UNAVAILABLE);
            customerAccountMapper.updateByExampleSelective(po,example);
            updateRoleInfo(ro.getUserSourceId(), ro.getSystemSign(), ro.getSubSystemSign(), CustomerConstants.STATUS_ACCOUNT_UNAVAILABLE);
        } catch (Exception e) {
            log.error("删除客户账户信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
        }
    }

    @Override
    public void syncCustomerAccount(List<CustomerAccountInfoRo> accounts) {
        for (CustomerAccountInfoRo ro : accounts) {
            syncCustomerAccount(ro);
        }
    }

    private String getSystemName(String systemSign, String subSystemSign) {
        SystemInfoPo systemInfo = commonService.getSystemInfo(systemSign, subSystemSign);
        return systemInfo.getSystemName();
    }
    @Override
    public void addRoleInfo(String userSourceId, String customerNo, String systemSign, String subSystemSign, String customerRole, Integer roleStatus) {
        CustomerRolePo currentRole = commonService.getCustomerRole(customerNo, customerRole, systemSign, subSystemSign);
        if(currentRole == null ){
            CustomerRolePo po = new CustomerRolePo();
            po.setUserSourceId(userSourceId);
            po.setId(UUIDUtils.getUUID());
            po.setCreateTime(new Timestamp(System.currentTimeMillis()));
            po.setCustomerNo(customerNo);
            po.setCustomerRole(customerRole);
            po.setRoleStatus(roleStatus);
            if (roleStatus == null) {
                po.setRoleStatus(CustomerConstants.STATUS_ACCOUNT_AVAILABLE);
            }
            po.setSystemSign(systemSign);
            po.setSubSystemSign(subSystemSign);
            customerRoleMapper.insert(po);
        }else{
            currentRole.setRoleStatus(roleStatus);
            currentRole.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            customerRoleMapper.updateByPrimaryKeySelective(currentRole);
        }
    }
        @Override
        public void updateRoleInfoByProduct(String userSourceId, String systemSign, String subSystemSign, Integer accountStatus) {
            CustomerRolePo po = new CustomerRolePo();
            po.setUserSourceId(userSourceId);
            po.setSystemSign(systemSign);
            po.setSubSystemSign(subSystemSign);
            po = customerRoleMapper.selectOne(po);
            po.setRoleStatus(accountStatus);
            po.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            customerRoleMapper.updateByPrimaryKeySelective(po);
        }

        private void updateRoleInfo(String userSourceId, String systemSign, String subSystemSign, Integer accountStatus) {
        CustomerRolePo po = new CustomerRolePo();
        po.setUserSourceId(userSourceId);
        po.setSystemSign(systemSign);
        po.setSubSystemSign(subSystemSign);
        po = customerRoleMapper.selectOne(po);
        if (accountStatus.equals(CustomerConstants.STATUS_ACCOUNT_AVAILABLE)) {
            po.setRoleStatus(CustomerConstants.CUSTOMER_ROLE_EFFECTIVE );
        } else {

            getRoleStatus(po,userSourceId,subSystemSign,systemSign,po.getCustomerRole());
           // po.setRoleStatus(CustomerConstants.CUSTOMER_ROLE_UNEFFECTIVE);
        }
        po.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        customerRoleMapper.updateByPrimaryKeySelective(po);
    }
    private void getRoleStatus(CustomerRolePo po, String userSourceId, String subSystemSign, String systemSign, String customerRole) {
        Example example = new Example(CustomerAccountPo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("subSystemSign",subSystemSign);
        criteria.andEqualTo("customerNo",po.getCustomerNo());
        criteria.andEqualTo("accountStatus",CustomerConstants.STATUS_ACCOUNT_AVAILABLE);
        //根据账户信息确认
        if("DLR".equals(subSystemSign) || "HYR".equals(subSystemSign) || "HYD".equals(subSystemSign) || "HHR".equals(systemSign)){
            //根据账户类型判断是否可用
            criteria.andEqualTo("accountType",po.getCustomerRole());
        };
        int i = customerAccountMapper.selectCountByExample(example);
        if (i<1){
            po.setRoleStatus(CustomerConstants.CUSTOMER_ROLE_UNEFFECTIVE);
        }else{
            po.setRoleStatus(CustomerConstants.CUSTOMER_ROLE_EFFECTIVE);
        }

    }

    private void updateRoleInfo(String userSourceId, CustomerAccountPo po, CustomerAccountInfoRo ro) {

        CustomerRolePo rolePo = new CustomerRolePo();
        rolePo.setUserSourceId(userSourceId);
        rolePo.setSystemSign(po.getSystemSign());
        rolePo.setSubSystemSign(po.getSubSystemSign());
        rolePo = customerRoleMapper.selectOne(rolePo);
        if (rolePo !=null) {
            String sourceCustomerNo = ro.getCustomerNo();
            log.info("sourceCustomerNo--------------------------------------------" + sourceCustomerNo);
            String roleCustomerNo = rolePo.getCustomerNo();
            log.info("roleCustomerNo--------------------------------------------" + roleCustomerNo);
            if (sourceCustomerNo != null && !sourceCustomerNo.equals(roleCustomerNo)) {
                rolePo.setCustomerNo(sourceCustomerNo);
            }
            Integer accountStatus0 = po.getAccountStatus();
            Integer accountStatus1 = ro.getAccountStatus();
            if (!accountStatus0.equals(accountStatus1) || "3".equals(po.getAccountType()) ) {
                if (accountStatus1.equals(CustomerConstants.STATUS_ACCOUNT_AVAILABLE) || "3".equals(po.getAccountType())) {
                    rolePo.setRoleStatus(CustomerConstants.CUSTOMER_ROLE_EFFECTIVE);
                } else {
                    rolePo.setRoleStatus(CustomerConstants.CUSTOMER_ROLE_UNEFFECTIVE);
                }
            }
            rolePo.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            customerRoleMapper.updateByPrimaryKeySelective(rolePo);
        }
    }

    private void addRelationInfo() {

    }
}

